package com.qf.openapi.wxpay.utils;

import cn.hutool.core.util.XmlUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;

import java.util.*;

public class WxPayTest {

    public static final String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    public static final String appid = "wx632c8f211f8122c6";
    public static final String mch_id = "1497984412";
    public static final String appkey = "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";

    public static void main(String[] args) {

//        test1();
        // 如何调用微信接口
        // 1. 准备参数map,把必传参数放入map中
        HashMap<String, String> map = new HashMap<>();
        String randomStr = UUID.randomUUID().toString().replaceAll("-", "");
        map.put("appid",appid); // appid
        map.put("mch_id",mch_id); //商户号
        map.put("nonce_str",randomStr); // 长度32个字符的随机字符串，干扰项
        map.put("out_trade_no","202307130928009"); // 商户自己的订单编号
        map.put("total_fee","1"); // 订单的总金额，单位分
        map.put("trade_type","NATIVE"); // 支付类型
        map.put("fee_type","CNY"); // 币种
        map.put("body","testproduct"); // 订单描述信息
        map.put("notify_url","http://47.118.45.73:8080/pay/callback"); // 商户提供的回调地址
        map.put("sign_type","MD5"); // 签名算法

        //2. 按照微信接口的签名规则计算签名，并且把签名也放入map中
        String sign = getSign(map,appkey);
        map.put("sign",sign);

        //3. map ----> xml
        String requestXml = XmlUtil.mapToXmlStr(map);

        //4. 发送请求给微信接口
        String result = HttpRequest.post(url).body(requestXml).execute().body();

//        System.out.println(result);

        //5. 把结果字符串转换成 map
        Map<String, Object> resultMap = XmlUtil.xmlToMap(result);
        System.out.println(resultMap);

    }

    /**
     * 微信规则的签名算法
     * @param map 所有参数的map
     * @param appkey 商户的appkey
     * @return
     */
    private static String getSign(HashMap<String, String> map, String appkey) {

        // 1. 使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。
        Set<String> paramNameSet = map.keySet();  // 从map中获取所有参数的名字即，map的key

        // paramNameSet ---> List<String>
        ArrayList<String> paramList = new ArrayList<>(paramNameSet);

        // 对list进行排序
        paramList.sort(String::compareTo);
//        System.out.println(paramList);

        StringBuffer stringBuffer = new StringBuffer();
        for (String key : paramList) {
            String value = map.get(key);
            if (value==null) {
                continue;
            }
            stringBuffer.append(key+"="+value);
            stringBuffer.append("&");
        }
        String stringA = stringBuffer.toString();
        System.out.println("StringA="+stringA);

        // 2. 在stringA最后拼接上key得到stringSignTemp字符串，并对stringSignTemp进行MD5运算
        String stringSignTemp = stringA + "key=" + appkey;
        System.out.println(stringSignTemp);

        // 使用hutool的md5工具计算md5值
        String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase();
        System.out.println(sign);
        return sign;
    }

    private static void test1() {
        String requestXML = "<xml>\n" +
                "   <appid>wx2421b1c4370ec43b</appid>\n" +
                "   <attach>支付测试</attach>\n" +
                "   <body>JSAPI支付测试</body>\n" +
                "   <mch_id>10000100</mch_id>\n" +
                "   <detail><![CDATA[{ \"goods_detail\":[ { \"goods_id\":\"iphone6s_16G\", \"wxpay_goods_id\":\"1001\", \"goods_name\":\"iPhone6s 16G\", \"quantity\":1, \"price\":528800, \"goods_category\":\"123456\", \"body\":\"苹果手机\" }, { \"goods_id\":\"iphone6s_32G\", \"wxpay_goods_id\":\"1002\", \"goods_name\":\"iPhone6s 32G\", \"quantity\":1, \"price\":608800, \"goods_category\":\"123789\", \"body\":\"苹果手机\" } ] }]]></detail>\n" +
                "   <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>\n" +
                "   <notify_url>https://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>\n" +
                "   <out_trade_no>1415659990</out_trade_no>\n" +
                "   <total_fee>1</total_fee>\n" +
                "   <trade_type>JSAPI</trade_type>\n" +
                "   <sign>0CB01533B8C1EF103065174F50BCA001</sign>\n" +
                "</xml>";

        // 如何发送http请求给指定的url
        String response = HttpRequest.post(url).body(requestXML).execute().body();

        System.out.println(response);
    }
}
